package org.zuel.huhuForum.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import static org.zuel.huhuForum.util.DesensitizeUtil.desensitize;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.zuel.huhuForum.component.SendMsg;
import org.zuel.huhuForum.constant.CommunityConstant;
import org.zuel.huhuForum.model.Comment;
import org.zuel.huhuForum.model.DiscussPost;
import org.zuel.huhuForum.model.User;
import org.zuel.huhuForum.param.Event;
import org.zuel.huhuForum.param.Page;
import org.zuel.huhuForum.service.ICommentService;
import org.zuel.huhuForum.service.IDiscussPostService;
import org.zuel.huhuForum.service.ILikeService;
import org.zuel.huhuForum.service.IUserService;
import org.zuel.huhuForum.service.Impl.FollowService;
import org.zuel.huhuForum.util.CommunityUtil;
import org.zuel.huhuForum.util.HostHolder;
import org.zuel.huhuForum.util.RedisKeyUtil;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotEmpty;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@RestController
@RequestMapping("/discuss")
@Api(tags = "帖子")
@Log4j2
public class DiscussPostController implements CommunityConstant{

    @Autowired
    private IDiscussPostService discussPostService;

    @Autowired
    private HostHolder hostHolder;

    @Autowired
    private FollowService followService;

    @Autowired
    private IUserService userService;

    @Autowired
    private ICommentService commentService;

    @Autowired
    private ILikeService likeService;

    @Autowired
    private SendMsg eventProducer;

    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 添加帖子（发帖）
     * @param title
     * @param content
     * @param theme
     * @return
     */
    @CrossOrigin
    @PostMapping("/add")
    @ApiOperation(value = "添加帖子（发帖）")
    @ResponseBody
    public String addDiscussPost(@RequestParam(name="title", required = true)String title,
                                 @RequestParam(name="content", required = true)String content,
                                 @RequestParam(name="theme", required = true)String theme) {
        User user = hostHolder.getUser();
        if (user == null) {
            return CommunityUtil.getJSONString(403, "您还未登录");
        }

        // 触发发帖事件，通过消息队列将其存入 Elasticsearch 服务器
        Event event = new Event()
                .setTopic(CommunityConstant.TOPIC_PUBLISH)
                .setUserId(user.getId())
                .setEntityType(CommunityConstant.ENTITY_TYPE_POST)
                .setEntityId(-1)
                .setData("UserId",user.getId())
                .setData("Title",title)
                .setData("Content",content)
                .setData("CreateTime",LocalDateTime.now())
                .setData("Theme",theme);
        eventProducer.addEvent(event);

        return CommunityUtil.getJSONString(200, "发布成功");
    }


    /**
     * 更新帖子（改帖）
     * @param id
     * @param title
     * @param content
     * @param theme
     * @return
     */
    @CrossOrigin
    @PostMapping("/update")
    @ApiOperation(value = "修改帖子（改帖）")
    public String updateDiscussPost(@RequestParam(name="postId", required = true)@NotEmpty(message = "更新主键不能为空")Integer id,
                                 @RequestParam(name="title", required = true)@NotEmpty(message = "文章标题不能为空") String title,
                                 @RequestParam(name="content", required = true)String content,
                                 @RequestParam(name="theme", required = true)String theme) {
        User user = hostHolder.getUser();
        if (user == null) {
            return CommunityUtil.getJSONString(403, "您还未登录");
        }
        DiscussPost discussPost = new DiscussPost();
        discussPost.setId(id);
        discussPost.setUserId(user.getId());
        discussPost.setTitle(title);
        discussPost.setContent(content);
        discussPost.setTheme(theme);
        discussPostService.updateDiscussPost(discussPost);
        //异步修改
        Event event = new Event()
                .setTopic(CommunityConstant.TOPIC_CHANGE)
                .setUserId(user.getId())
                .setEntityType(CommunityConstant.ENTITY_TYPE_POST)
                .setEntityId(discussPost.getId());
        eventProducer.searchEvent(event);

        return CommunityUtil.getJSONString(200, "发布成功");
    }

    /**
     * 置顶帖子
     * @param id
     * @return
     */
    @CrossOrigin
    @PostMapping("/top")
    @ApiOperation(value = "置顶/取消置顶帖子")
    public String updateTop(@RequestParam(name="id", required = true)int id,
                            @RequestParam(name="type", required = true)int type) {

        discussPostService.updateType(id, type);
        // 异步将信息同步到elasticsearch中
        Event event = new Event()
                .setTopic(CommunityConstant.TOPIC_CHANGE)
                .setUserId(hostHolder.getUser().getId())
                .setEntityType(CommunityConstant.ENTITY_TYPE_POST)
                .setEntityId(id);
        eventProducer.searchEvent(event);

        return CommunityUtil.getJSONString(200);
    }

    /**
     * 加精帖子
     * @param id
     * @return
     */
    @CrossOrigin
    @PostMapping("/wonderful")
    @ApiOperation(value = "加精帖子")
    public String setWonderful(@RequestParam(name="id", required = true)int id) {
        // 异步修改
        Event event = new Event()
                .setTopic(CommunityConstant.TOPIC_CHANGE)
                .setUserId(hostHolder.getUser().getId())
                .setEntityType(CommunityConstant.ENTITY_TYPE_POST)
                .setEntityId(id)
                .setData("status", TYPE_ONE);
        eventProducer.addEvent(event);

        // 计算帖子分数
        String redisKey = RedisKeyUtil.getPostScoreKey();
        redisTemplate.opsForSet().add(redisKey, id);

        return CommunityUtil.getJSONString(200);
    }

    /**
     * 拉黑帖子
     * @param id
     * @return
     */
    @CrossOrigin
    @PostMapping("/over")
    @ApiOperation(value = "终结帖子")
    public String setOver(@RequestParam(name="id", required = true)int id) {
        // 触发发帖事件，通过消息队列将其存入 Elasticsearch 服务器
        Event event = new Event()
                .setTopic(CommunityConstant.TOPIC_CHANGE)
                .setUserId(hostHolder.getUser().getId())
                .setEntityType(CommunityConstant.ENTITY_TYPE_POST)
                .setEntityId(id)
                .setData("status", TYPE_THERE);
        eventProducer.addEvent(event);

        // 计算帖子分数
        String redisKey = RedisKeyUtil.getPostScoreKey();
        redisTemplate.opsForSet().add(redisKey, id);

        return CommunityUtil.getJSONString(200);
    }

    /**
     * 删除帖子
     * @param id
     * @return
     */
    @CrossOrigin
    @PostMapping("/delete")
    @ApiOperation(value = "删除帖子")
    public String setDelete(@RequestParam(name="postid", required = true)int id) {
        // 触发删帖事件，通过消息队列更新 Elasticsearch 服务器
        Event event = new Event()
                .setTopic(CommunityConstant.TOPIC_DELETE)
                .setUserId(hostHolder.getUser().getId())
                .setEntityType(CommunityConstant.ENTITY_TYPE_POST)
                .setEntityId(id);
        eventProducer.addEvent(event);

        // 计算帖子分数
        String redisKey = RedisKeyUtil.getPostScoreKey();
        redisTemplate.opsForSet().add(redisKey, id);

        return CommunityUtil.getJSONString(200);
    }

    /**
     * 删除帖子
     * @param id
     * @return
     */
    @CrossOrigin
    @PostMapping("/setReturn")
    @ApiOperation(value = "恢复帖子")
    public String setreturn(@RequestParam(name="postid", required = true)int id) {
        // 触发发帖事件，通过消息队列将其存入 Elasticsearch 服务器
        Event event = new Event()
                .setTopic(CommunityConstant.TOPIC_CHANGE)
                .setUserId(hostHolder.getUser().getId())
                .setEntityType(CommunityConstant.ENTITY_TYPE_POST)
                .setEntityId(id)
                .setData("status", TYPE_ZERO);
        eventProducer.addEvent(event);

        // 计算帖子分数
        String redisKey = RedisKeyUtil.getPostScoreKey();
        redisTemplate.opsForSet().add(redisKey, id);

        return CommunityUtil.getJSONString(200);
    }


    /**
     * 删除帖子
     * @param id
     * @return
     */
    @CrossOrigin
    @PostMapping("/deletesearch")
    @ApiOperation(value = "删除查询")
    public String setDeleteSearch(@RequestParam(name="postid", required = true)int id) {
        // 触发删帖事件，通过消息队列更新 Elasticsearch 服务器
        Event event = new Event()
                .setTopic(CommunityConstant.TOPIC_DELETE)
                .setUserId(hostHolder.getUser().getId())
                .setEntityType(CommunityConstant.ENTITY_TYPE_POST)
                .setEntityId(id);
        eventProducer.searchEvent(event);

        return CommunityUtil.getJSONString(200);
    }

    /**
     * 进入帖子详情页
     * @param discussPostId
     * @return
     */
    @ApiOperation(value = "进入帖子详情页")
    @CrossOrigin
    @PostMapping("/detail")
    public Map<String, Object> getDiscussPost(@RequestParam(name="discussPostId", required = true) int discussPostId
            , @RequestParam(name = "current",required = false,defaultValue ="1") Integer current, HttpServletRequest request) {
        String ticket=request.getHeader("ticket");
        Integer userid;
        if(hostHolder.getUser()!=null){
            userid=hostHolder.getUser().getId();
        }else{
            userid=0;
        }
        Map<String, Object>model=new HashMap<>();
        // 帖子
        DiscussPost discussPost = discussPostService.findDiscussPostById(discussPostId);

        if(discussPost.getStatus().equals(TYPE_TWE)){
            model.put("data", "该帖已被屏蔽！");
            model.put("code", "23");
            model.put("msg", "error");
            return model;
        }
        Event event=new Event();
        event.setUserId(userid)
                .setEntityId(discussPostId)
                .setTopic("readed")
                .setData("theme", discussPost.getTheme());
        eventProducer.readEvent(event);
//        String content = HtmlUtils.htmlUnescape(discussPost.getContent()); // 内容反转义，不然 markDown 格式无法显示
//        discussPost.setContent(content);
        model.put("post", discussPost);
        // 作者
        User user = userService.findUserById(discussPost.getUserId());
        model.put("user",desensitize(user));
        boolean isfollow=false;
        if(hostHolder.getUser()!=null){
            isfollow=followService.hasFollowed(hostHolder.getUser().getId(), ENTITY_TYPE_USER, user.getId());
        }
        model.put("isfollow", isfollow);
        // 点赞数量
        long likeCount = likeService.findEntityLikeCount(CommunityConstant.ENTITY_TYPE_POST, discussPostId);
        model.put("likeCount", likeCount);
        // 当前登录用户的点赞状态
        int likeStatus = hostHolder.getUser() == null ? 0 :
                likeService.findEntityLikeStatus(hostHolder.getUser().getId(), CommunityConstant.ENTITY_TYPE_POST, discussPostId);
        model.put("likeStatus", likeStatus);
        Page page=new Page();

        // 评论分页信息
        page.setLimit(5);
        page.setPath("/discuss/detail/" + discussPostId);
        page.setRows(discussPost.getCommentCount());

        // 帖子的评论列表
        List<Comment> commentList = commentService.findCommentByEntity(
                CommunityConstant.ENTITY_TYPE_POST, discussPost.getId(), page.getOffset(), page.getLimit());

        // 封装评论及其相关信息
        List<Map<String, Object>> commentVoList = new ArrayList<>();
        if (commentList != null) {
            for (Comment comment : commentList) {
                // 存储对帖子的评论
                Map<String, Object> commentVo = new HashMap<>();
                User target=desensitize(userService.findUserById(comment.getUserId()));
                commentVo.put("comment", comment); // 评论
                commentVo.put("user", target); // 发布评论的作者
                likeCount = likeService.findEntityLikeCount(CommunityConstant.ENTITY_TYPE_COMMENT, comment.getId()); // 该评论点赞数量
                commentVo.put("likeCount", likeCount);
                likeStatus = hostHolder.getUser() == null ? 0 : likeService.findEntityLikeStatus(
                        hostHolder.getUser().getId(), CommunityConstant.ENTITY_TYPE_COMMENT, comment.getId()); // 当前登录用户对该评论的点赞状态
                commentVo.put("likeStatus", likeStatus);
                isfollow= hostHolder.getUser() != null && followService.hasFollowed(
                        hostHolder.getUser().getId(), ENTITY_TYPE_USER, target.getId());
                commentVo.put("isfollow", isfollow);
                // 存储每个评论对应的回复（不做分页）
                List<Comment> replyList = commentService.findCommentByEntity(
                        CommunityConstant.ENTITY_TYPE_COMMENT, comment.getId(), 0, Integer.MAX_VALUE);
                List<Map<String, Object>> replyVoList = new ArrayList<>(); // 封装对评论的评论和评论的作者信息
                if (replyList != null) {
                    for (Comment reply : replyList) {
                        Map<String, Object> replyVo = new HashMap<>();
                        replyVo.put("reply", reply); // 回复
                        replyVo.put("user", desensitize(userService.findUserById(reply.getUserId()))); // 发布该回复的作者
//                        User target = reply.getTargetId() == 0 ? null : userService.findUserById(reply.getTargetId());
//                        replyVo.put("target", desensitize(target)); // 该回复的目标用户
                        likeCount = likeService.findEntityLikeCount(CommunityConstant.ENTITY_TYPE_COMMENT, reply.getId());
                        replyVo.put("likeCount", likeCount); // 该回复的点赞数量
                        likeStatus = hostHolder.getUser() == null ? 0 : likeService.findEntityLikeStatus(
                                hostHolder.getUser().getId(), CommunityConstant.ENTITY_TYPE_COMMENT, reply.getId());
                        replyVo.put("likeStatus", likeStatus); // 当前登录用户的点赞状态
                        replyVoList.add(replyVo);
                    }
                }

                commentVo.put("replys", replyVoList);

                // 每个评论对应的回复数量
                int replyCount = commentService.findCommentCount(CommunityConstant.ENTITY_TYPE_COMMENT, comment.getId());
                commentVo.put("replyCount", replyCount);

                commentVoList.add(commentVo);
            }
        }
        model.put("comments", commentVoList);
        model.put("page", page);
        return model;

    }
}
